import React, { memo, useCallback, useRef, useState } from 'react'

const HYIncrement = memo(function (props) {
  const { increment } = props
  console.log('HYIncrement被渲染')
  return (
    <div>
      <button onClick={increment}>+1</button>
    </div>
  )
})

const App = memo(function () {
  const [count, setCount] = useState(0)
  const [message, setMessage] = useState('hello')

  // 单纯的function每次渲染都会创建定义一次（会被反复销毁创建）
  // uesCallback会保持该函数，每次重新渲染时返回的是同一个函数，但是这个也是没有意义的，因为他内部的函数还是会被重新创建定义
  // 性能优化：将useCallback返回的函数传递给另外的组件，此时只有当前useCallback中依赖项发生改变时，才会重新渲染该组件
  /* const increment = useCallback(
    function () {
      console.log('increment')
      setCount(count + 1)
    },
    [count]
  ) */

  // 进一步优化：当count发生改变，已使用同一个函数
  // 解决一：将count依赖删除掉，缺点：闭包陷阱
  // 做法二：useRef，在组件多次渲染时，返回的是同一个值
  const countRef = useRef()
  countRef.current = count
  const increment = useCallback(function () {
    console.log('increment')
    setCount(countRef.current + 1)
  }, [])

  // 普通函数
  /* const increment = () => {
    console.log('increment')
    setCount(count + 1)
  } */

  return (
    <div>
      <h1>计数：{count}</h1>
      <button onClick={increment}>+1</button>

      <HYIncrement increment={increment} />

      <h2>{message}</h2>
      <button onClick={(e) => setMessage(Math.random() + '')}>
        修改message
      </button>
    </div>
  )
})

/* function foo(name) {
  function bar() {
    console.log(name)
  }

  return bar
}

const bar1 = foo('why')
bar1() // why

const bar2 = foo('kobe')
bar2() // kobe

bar1() // why */

export default App
